/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pe.edu.unmsm.cinfo.siga.login;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;

/**
 *
 * @author lartkma
 */
public class VerficarContrasenia {
    private String ruta, user, pass;
    private Connection conexion;
    private PreparedStatement preguntarXUsuario, preguntarXUsuarioClase;
    private static VerficarContrasenia that;
    
    public VerficarContrasenia() {
        try {
            Class.forName("org.firebirdsql.jdbc.FBDriver");
            obtenerDatosLogin();
            conexion = DriverManager.getConnection(ruta, user, pass);
            preguntarXUsuario = conexion.prepareStatement("SELECT * FROM USUARIO WHERE UPPER(NOMBRE) = ? and passEncriptado = ?");
            preguntarXUsuarioClase = conexion.prepareStatement("SELECT * FROM USUARIO WHERE UPPER(NOMBRE) = ? and passEncriptado = ? and clase = ?");
            if(!existeUsuarios()) crearRoot();
        } catch (ClassNotFoundException cnfex) {
            throw new SIGAException("Driver de acceso a BD no hallado. Contacte con el administrador");
        } catch (SQLException sqlex){
            throw new SIGAException("Error al conectarse. Contacte con el administrador\nCausa: "+sqlex.getMessage());
        } catch (IOException ioe){
            ioe.printStackTrace();
            throw new SIGAException("Error al leer datos");
        }
    }
    
    private void obtenerDatosLogin() throws IOException{
        Properties p = new Properties();
        p.loadFromXML(VerficarContrasenia.class.getResourceAsStream("login.xml"));
        ruta = p.getProperty("javax.persistence.jdbc.url");
        user = p.getProperty("javax.persistence.jdbc.user");
        pass = p.getProperty("javax.persistence.jdbc.password");
    }
    
    public boolean verificar(String usuario, String pass){
        try {
            preguntarXUsuario.setString(1, usuario.toUpperCase());
            preguntarXUsuario.setString(2, encriptar(pass));
            preguntarXUsuario.execute();
            return tieneElementos(preguntarXUsuario);
        } catch (SQLException sqlex) {
            throw new SIGAException("Error al ejecutar consulta. Contacte con el administrador\nCausa: "+sqlex.getMessage());
        }
    }
    
    public boolean verificar(String usuario, String pass, int clase){
        try {
            preguntarXUsuarioClase.setString(1, usuario.toUpperCase());
            preguntarXUsuarioClase.setString(2, encriptar(pass));
            preguntarXUsuarioClase.setInt(3, clase);
            preguntarXUsuarioClase.execute();
            return tieneElementos(preguntarXUsuarioClase);
        } catch (SQLException sqlex) {
            throw new SIGAException("Error al ejecutar consulta. Contacte con el administrador\nCausa: "+sqlex.getMessage());
        }
    }
    
    public String encriptar(String pass){
        try {
            String salt = "#o#o$", encoding = "ISO8859_1";
            MessageDigest encriptador = MessageDigest.getInstance("SHA-256");
            byte[] entrada = (pass+salt).getBytes(encoding);
            byte[] salida  = encriptador.digest(entrada);
            return new String(salida, encoding);
        } catch (NoSuchAlgorithmException ex) {
            throw new SIGAException("Error al encriptar");
        } catch (UnsupportedEncodingException ex){
            throw new SIGAException("Error al encriptar");
        }
    }
    
    public boolean tieneElementos(PreparedStatement query) throws SQLException{
        return query.getResultSet().next();
    }
    
    public static VerficarContrasenia get(){
        if(that == null) that = new VerficarContrasenia();
        return that;
    }
    
    public static void end(){
        try {
            if(that != null) that.conexion.close();
        } catch (SQLException ex) {
        }
        that = null;
    }
    
    public final boolean existeUsuarios() throws SQLException{
        PreparedStatement todos = conexion.prepareStatement("SELECT * FROM USUARIO");
        todos.execute();
        return tieneElementos(todos);
    }
    
    public final void crearRoot() throws SQLException{
        PreparedStatement insert = conexion.prepareStatement("INSERT INTO USUARIO VALUES(GEN_ID(USUARIOS_GEN, 1),?,?,?)");
        insert.setString(1, "root");
        insert.setString(2, encriptar("root"));
        insert.setInt(3, 1);
        insert.executeUpdate();
    }
}
